package com.gluck.cases.app.biz.impl.impl;

import com.gluck.cases.app.biz.impl.BasecService;
import com.gluck.cases.app.biz.impl.PermissionService;
import com.gluck.cases.common.utils.constants.BizSerConstant;
import com.gluck.cases.common.utils.enums.BizSerErrorEnum;
import com.gluck.cases.common.utils.annotations.PermissionControl;
import com.gluck.cases.common.utils.annotations.SyncPermissionTableAndField;
import com.gluck.cases.common.utils.exception.BizSerException;
import com.gluck.cases.common.utils.utils.AssertUtil;
import com.gluck.cases.common.utils.utils.ScanPackageUtils;
import com.gluck.cases.core.block.PermissionBlock;
import com.gluck.cases.core.modal.dto.PermissionListDTO;
import com.gluck.cases.core.modal.entity.Permission;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName PermissionServiceImpl
 * @Desc PermissionServiceImpl
 * @Author I am Gluck
 * @Date 2022/5/17 - 8:33 下午
 **/
@Service
public class PermissionServiceImpl extends BasecService implements PermissionService {


    @Autowired
    private PermissionBlock permissionBlock;

    @Override
    public List<Permission> findPermissionByRoleName(String name) {
        return permissionBlock.findPermissionByRoleName(name);
    }

    @Override
    public List<Permission> queryPermissionListByPid(Long pid) {
        return permissionBlock.queryPermissionListByPid(pid);
    }

    @Override
    public List<PermissionListDTO> queryPermissionList() {
        return permissionBlock.queryPermissionByList(0l);
    }

    @Override
    public boolean syncPermission() {
        Set<Class<?>> classes = ScanPackageUtils.startScan(BizSerConstant.SYNC_PACK_PATH);
        // step 1 获取有所有的包
        List<Class<?>> collect = classes.stream().collect(Collectors.toList());
        // step 2 没有抓取到包直接异常抛出
        AssertUtil.isTrue(Objects.isNull(collect) || collect.size() == 0, BizSerErrorEnum.SCAN_PACKAGE_NOT_FOUND);
        // step 3 过滤数据并转换
        List<String> list = buildPermission(collect);
        return false;
    }

    private List<String> buildPermission(List<Class<?>> collect) {
        List<String> permissions = collect
                .stream()
                .filter(x -> filterNoHavePermissionControl(x))
                .flatMap(y ->
                        queryPermissionCode(y.getMethods()).stream()
                )
                .collect(Collectors.toList());
        return permissions;
    }

    private List<String> queryPermissionCode(Method[] methods){
        try{
            List<String> result = Arrays
                .stream(methods)
                .filter(m -> filterNoHaveSyncPermission(m))
                .map(s -> {
                    return querySqlPermissionField(s);
                })
                .collect(Collectors.toList());
            return result;
        }catch (Exception e){
            throw new BizSerException(BizSerErrorEnum.SELECT_ERROR, e.getMessage());
        }
    }

    private String querySqlPermissionField(Method method) {
        String field = method.getAnnotation(SyncPermissionTableAndField.class).syncField();
        String table = method.getAnnotation(SyncPermissionTableAndField.class).syncTable();
        String value = method.getAnnotation(SyncPermissionTableAndField.class).syncThresholdValue();
        Map<String, String> sqlValueMap = queryPermissionField(field, table, field, value);
        // 动态查询数据库
        String p = table + ":"+ sqlValueMap.get(field) + ":" + field;
        return p;
    }

    private static boolean filterNoHaveSyncPermission(Method m) {
        SyncPermissionTableAndField syncPermissionTableAndField = m.getAnnotation(SyncPermissionTableAndField.class);
        if (Objects.nonNull(syncPermissionTableAndField)) {
            return true;
        }
        return false;
    }

    private static boolean filterNoHavePermissionControl(Class<?> y) {
        PermissionControl permissionControl = y.getAnnotation(PermissionControl.class);
        if (Objects.nonNull(permissionControl) && !permissionControl.isFilter()) {
            return true;
        }
        return false;
    }
}
